home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 18
/
CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso
/
CUCD
/
Programming
/
AmigaE
/
Src
/
Various
/
radix.e
< prev
next >
Wrap
Text File
|
1994-11-08
|
2KB
|
109 lines
/* Super fast sort program.
whereas slow methods like quicksort/mergesort use O(n * log n) methods,
radixsort is a true O(n) method. Especially for large textfiles, it is a
LOT faster than other sorters (a log order of magnitude ;-).
Radixsort uses a 256 buckets at each level to put the strings in. arrays
of buckets are only allocated when the number of strings left to sort is
large.
Radix.e reads from a file, and outputs to stdout.
*/
MODULE 'tools/file', 'tools/exceptions'
DEF rad1:PTR TO LONG,radsize:PTR TO LONG
OBJECT str
next,data
ENDOBJECT
PROC main() HANDLE
DEF m,l,n,list
m,l:=readfile(arg)
n:=countstrings(m,l)
list:=stringsinfilenolist(m,l,n)
doradix(NEW rad1[256],NEW radsize[256],list,n)
restradix(rad1,radsize)
EXCEPT
report_exception()
ENDPROC
PROC doradix(table:PTR TO LONG,size:PTR TO LONG,str:PTR TO LONG,num)
DEF a,s,c
FOR a:=1 TO num
s:=str[]++
c:=s[]
table[c]:=NEW [table[c],s]:str
size[c]:=size[c]+1
ENDFOR
ENDPROC
PROC restradix(table:PTR TO LONG,size:PTR TO LONG,level=1)
DEF a
FOR a:=0 TO 255 DO recradix(table[]++,size[]++,level)
ENDPROC
PROC recradix(l:PTR TO str,num,level)
DEF tab:PTR TO LONG,size:PTR TO LONG,s,c,temp:PTR TO str
IF num
IF num<20
straight(l,num)
ELSE
NEW tab[256],size[256]
WHILE l
s:=l.data
temp:=l
l:=l.next
c:=s[level]
temp.next:=tab[c]
tab[c]:=temp
size[c]:=size[c]+1
ENDWHILE
restradix(tab,size,level+1)
END tab[256],size[256]
ENDIF
ENDIF
ENDPROC
PROC straight(l:PTR TO str,num) -> sort these with a silly method
DEF a,tl:PTR TO str,best:PTR TO str,fbest
fbest:=[NIL,[$7F7F7F7F,$7F7F7F7F,$7F7F7F7F,0]:LONG]:str
FOR a:=1 TO num
tl:=l
best:=fbest
WHILE tl
IF tl.data THEN IF OstrCmp(best.data,tl.data)=-1 THEN best:=tl
tl:=tl.next
ENDWHILE
IF best<>fbest
PutStr(best.data)
FputC(stdout,"\n")
best.data:=NIL
ENDIF
ENDFOR
ENDPROC
PROC stringsinfilenolist(mem,len,max) -> to eliminate 32k strings boundary
DEF list:PTR TO LONG,l
NEW list[max]
MOVE.L list,A1
MOVE.L max,D3
MOVE.L mem,A0
MOVE.L A0,D1
ADD.L len,D1
MOVEQ #0,D0
MOVEQ #10,D2
stringsl:
CMP.L D3,D0
BPL.S done
ADDQ.L #1,D0
MOVE.L A0,(A1)+
findstringl:
CMP.B (A0)+,D2
BNE.S findstringl
CLR.B -1(A0)
CMPA.L D1,A0
BMI.S stringsl
done:
MOVE.L D0,l
ENDPROC list,l